import xlrd
from interface.utils.demo import RunMain
import abc
import threading
import json
from common.handle_getValue import *
from common.handle_config import *
from interface.utils.getSheetIndex import *

token = ""
excel_data = xlrd.open_workbook(os.path.dirname(os.path.dirname(__file__)) + "/data/" + "api.xlsx")


class Handle_Data(object):
    def __init__(self, index, sheet_index):
        self.sheet_index = sheet_index
        self.table = excel_data.sheets()[sheet_index]
        # 创建请求对象实例请求地址
        self.run = RunMain()
        # 打开excel文档
        self.index = index
        self.url = self.table.row_values(self.index)[0]
        self.method = self.table.row_values(index)[1]
        self.res_json = ""
        # 行数
        self.rows = self.table.nrows
        # 列数
        self.cols = self.table.ncols
        self.res = ""
        self.data = ""
        self.headers = ""

    def set_data(self):
        if self.method.lower() == "post":
            self.data = json.loads(self.table.row_values(self.index)[2])
            if self.table.row_values(self.index)[10] != "":
                variable = self.table.row_values(self.index)[10]
                section = get_discount(self.sheet_index)
                value = OperateConfig().confRead(section, variable)
                self.data["body"][variable] = value
            if "token" in str(self.data):
                self.get_tokenId()
            return self.data
        if self.method.lower() == "get":
            return self.data is None

    def set_headers(self):
        if self.table.row_values(self.index)[3] != "":
            self.headers = eval(self.table.row_values(self.index)[3])
            if "login" not in self.url and "admin" in self.url:
                if "access-token" in list(self.headers.keys()):
                    self.get_tokenId()
            return self.headers
        else:
            return self.headers is None

    def set_url(self):
        return self.url

    @abc.abstractmethod
    def get_tokenId(self):
        # 运营端获取token
        if "login" not in self.url and "getPhone" not in self.url:
            if "admin" in self.url:
                self.headers["access-token"] = token
                return self.headers
            else:
                self.data["header"]["token"] = token
                return self.data

    # 接口判断
    def interface_callback(self):
        res_json = self.res.json()
        print(res_json)
        if "login" in self.url or "getPhone" in self.url:
            global token
            token = res_json["data"]["token"]
        # 判断是否存在提取参数
        if self.table.row_values(self.index)[9] != "":
            res_json = self.res.json()
            keyword = self.table.row_values(self.index)[9]
            # 根据关键字获取参数,将提取参数放进对应节点的选项中
            parameter = GetValue().getValue(data=res_json, keyword=keyword)
            section = get_discount(self.sheet_index)
            OperateConfig().confWrite(section=section, option=keyword, value=parameter)

    def get_response(self):
        try:
            url = self.set_url()
            headers = self.set_headers()
            data = self.set_data()
            print("请求地址:", url)
            print("请求头:", headers)
            print("请求体:", data)
        except Exception as e:
            print("请求参数不正确", e)
        self.res = self.run.run_main(url, self.method, data, headers)
        print(f"接口请求耗时:{self.res.elapsed.total_seconds()}秒")

    def assert_result(self):
        if self.method.upper() == "POST":
            res_json = self.res.json()
            # 先断言url返回的结果，一般为200才继续后面流程
            assert (self.res.status_code == 200)
            self.interface_callback()
            # 判断返回值的长度
            if self.table.row_values(self.index)[4] == 1:
                assert (len(res_json) > 0)
            if self.table.row_values(self.index)[5] != "":
                result_1 = self.table.row_values(self.index)[5]
                if isinstance(result_1, float) or isinstance(result_1, int):
                    result_1 = str(int(result_1))
                print(result_1 in json.dumps(res_json, ensure_ascii=False))
                assert (self.table.row_values(self.index)[5]
                        in json.dumps(res_json, ensure_ascii=False))
            # 多线程压力测试，excel中第7列数字是多少，并发多少次
            if self.table.row_values(self.index)[6] != "":
                thread_pool = []
                for i in range(int(self.table.row_values(self.index)[6])):
                    th = threading.Thread(target=self.get_response)
                    thread_pool.append(th)
                for th in thread_pool:
                    th.start()
                for th in thread_pool:
                    threading.Thread.join(th)
            if self.table.row_values(self.index)[7] != "":
                result_2 = self.table.row_values(self.index)[7]
                if isinstance(result_2, float) or isinstance(result_2, int):
                    result_2 = str(int(result_2))
                assert (result_2 in json.dumps(res_json, ensure_ascii=False))
            else:
                assert True
            if self.table.row_values(self.index)[8] != "":
                result_3 = self.table.row_values(self.index)[8]
                if isinstance(result_3, float) or isinstance(result_3, int):
                    result_3 = str(int(result_3))
                assert (result_3 in json.dumps(res_json, ensure_ascii=False))
            else:
                assert True
        # get请求只判断返回的code
        elif self.method.upper() == "GET":
            assert (self.res.status_code == 200)
        else:
            assert False
